@@ -0,0 +1,38 @@  | 
            ||
| 1 | 
                +# -*- coding: utf-8 -*-  | 
            |
| 2 | 
                +  | 
            |
| 3 | 
                +from __future__ import division  | 
            |
| 4 | 
                +  | 
            |
| 5 | 
                +from paginator import pagination  | 
            |
| 6 | 
                +  | 
            |
| 7 | 
                +from django.db import transaction  | 
            |
| 8 | 
                +from django.db.models import Q  | 
            |
| 9 | 
                +from django_logit import logit  | 
            |
| 10 | 
                +  | 
            |
| 11 | 
                +from kodo.decorators import check_admin  | 
            |
| 12 | 
                +from mch.models import AdministratorInfo, ConsumeShotUnbindingInfo  | 
            |
| 13 | 
                +  | 
            |
| 14 | 
                +  | 
            |
| 15 | 
                +@logit  | 
            |
| 16 | 
                +@check_admin  | 
            |
| 17 | 
                +def consumer_shot_unbinding_list(request, administrator):  | 
            |
| 18 | 
                +    start_time = request.POST.get('start_time', '')
               | 
            |
| 19 | 
                +    end_time = request.POST.get('end_time', '')
               | 
            |
| 20 | 
                +    query = request.POST.get('query', '')
               | 
            |
| 21 | 
                +  | 
            |
| 22 | 
                + unbindings = ConsumeShotUnbindingInfo.objects.filter(Q(phone__icontains=query) | Q(sn__icontains=query), status=True)  | 
            |
| 23 | 
                +  | 
            |
| 24 | 
                + if start_time and end_time:  | 
            |
| 25 | 
                + start_time = tc.string_to_utc_datetime(start_time, format='%Y%m%d')  | 
            |
| 26 | 
                + end_time = tc.string_to_utc_datetime(end_time + ' 23:59:59', format='%Y%m%d %H:%M:%S')  | 
            |
| 27 | 
                + unbindings = unbindings.filter(created_at__range=(start_time, end_time))  | 
            |
| 28 | 
                +  | 
            |
| 29 | 
                + count = unbindings.count()  | 
            |
| 30 | 
                +  | 
            |
| 31 | 
                + unbindings, left = pagination(unbindings, page, num)  | 
            |
| 32 | 
                + unbindings = [unbinding.admindata for unbinding in unbindings]  | 
            |
| 33 | 
                +  | 
            |
| 34 | 
                +    return response(200, 'Get Cosumer Shot Unbinding List Success', u'用户列表获取成功', data={
               | 
            |
| 35 | 
                + 'unbinding': userinfos,  | 
            |
| 36 | 
                + 'count': count,  | 
            |
| 37 | 
                + 'left': left  | 
            |
| 38 | 
                + })  | 
            
                @@ -19,7 +19,7 @@ from coupon.models import CouponInfo, UserCouponInfo  | 
            ||
| 19 | 19 | 
                from integral.models import SaleclerkSubmitLogInfo  | 
            
| 20 | 20 | 
                from logs.models import AdministratorLoginLogInfo, MchInfoEncryptLogInfo  | 
            
| 21 | 21 | 
                from mch.models import (ActivityInfo, AdministratorInfo, BrandInfo, ConsumeInfoSubmitLogInfo, DistributorInfo,  | 
            
| 22 | 
                - LatestAppInfo, LatestAppScreenInfo, ModelInfo, OperatorInfo)  | 
            |
| 22 | 
                + LatestAppInfo, LatestAppScreenInfo, ModelInfo, OperatorInfo, ConsumeShotUnbindingInfo)  | 
            |
| 23 | 23 | 
                from statistic.models import ConsumeModelSaleStatisticInfo, ConsumeSaleStatisticInfo, ConsumeUserStatisticInfo  | 
            
| 24 | 24 | 
                from utils.error.errno_utils import (AdministratorStatusCode, OperatorStatusCode, ProductBrandStatusCode,  | 
            
| 25 | 25 | 
                ProductModelStatusCode, UserStatusCode)  | 
            
                @@ -521,3 +521,31 @@ def consumer_model_list(request):  | 
            ||
| 521 | 521 | 
                     return response(200, 'Get Model List Success', u'获取型号列表成功', {
               | 
            
| 522 | 522 | 
                'models': models,  | 
            
| 523 | 523 | 
                })  | 
            
| 524 | 
                +  | 
            |
| 525 | 
                +  | 
            |
| 526 | 
                +@logit(res=True)  | 
            |
| 527 | 
                +@transaction.atomic  | 
            |
| 528 | 
                +def consumer_shot_unbinding(request):  | 
            |
| 529 | 
                +    user_id = request.POST.get('user_id', '')
               | 
            |
| 530 | 
                +    submit_pk = request.POST.get('id', '')
               | 
            |
| 531 | 
                +    submit_at = request.POST.get('created_at', '')
               | 
            |
| 532 | 
                +    model_id = request.POST.get('model_id', '')
               | 
            |
| 533 | 
                +    sn = request.POST.get('serialNo', '')
               | 
            |
| 534 | 
                +    reason = request.POST.get('reason', '')
               | 
            |
| 535 | 
                +  | 
            |
| 536 | 
                + # 校验用户是否存在  | 
            |
| 537 | 
                + try:  | 
            |
| 538 | 
                + user = UserInfo.objects.get(user_id=user_id)  | 
            |
| 539 | 
                + except UserInfo.DoesNotExist:  | 
            |
| 540 | 
                + return response(UserStatusCode.USER_NOT_FOUND)  | 
            |
| 541 | 
                +  | 
            |
| 542 | 
                +    ConsumeShotUnbindingInfo.objects.update_or_create(user_id=user_id, submit_pk=submit_pk, defaults={
               | 
            |
| 543 | 
                + 'model_id': model_id,  | 
            |
| 544 | 
                + 'sn': sn,  | 
            |
| 545 | 
                + 'submit_at': submit_at,  | 
            |
| 546 | 
                + 'reason': reason,  | 
            |
| 547 | 
                + })  | 
            |
| 548 | 
                +  | 
            |
| 549 | 
                + return response(200, 'Consume Shot Unbinding Success', u'消费者镜头解绑成功')  | 
            |
| 550 | 
                +  | 
            |
| 551 | 
                +  | 
            
                @@ -6,7 +6,7 @@ from django_file_upload import views as file_views  | 
            ||
| 6 | 6 | 
                from api import (admin_views, clerk_views, complement_views, distributor_views, encrypt_views, express_views, log_views,  | 
            
| 7 | 7 | 
                maintenance_point_views, maintenance_views, mch_views, member_views, model_views, operator_views,  | 
            
| 8 | 8 | 
                refresh_views, sr_views, staff_views, tenancy_admin_views, tenancy_views, tencentcloud_views, wx_views,  | 
            
| 9 | 
                - wxa_views)  | 
            |
| 9 | 
                + wxa_views, consumer_admin_view)  | 
            |
| 10 | 10 | 
                from miniapp import qy_views  | 
            
| 11 | 11 | 
                from miniapp import views as mini_views  | 
            
| 12 | 12 | 
                from page import oauth_views, sale_views, screen_views  | 
            
                @@ -58,7 +58,8 @@ urlpatterns += [  | 
            ||
| 58 | 58 | 
                url(r'^consumer_phone$', mch_views.consumer_phone_api, name='consumer_phone_api'),  | 
            
| 59 | 59 | 
                url(r'^consumer_info$', mch_views.consumer_info_api, name='consumer_info_api'),  | 
            
| 60 | 60 | 
                url(r'^consumer_snlist$', mch_views.consumer_snlist_api, name='consumer_snlist_api'),  | 
            
| 61 | 
                - url(r'^consumer_model_list$', mch_views.consumer_model_list, name='consumer_model_list')  | 
            |
| 61 | 
                + url(r'^consumer_model_list$', mch_views.consumer_model_list, name='consumer_model_list'),  | 
            |
| 62 | 
                + url(r'^consumer/shot/unbinding$', mch_views.consumer_shot_unbinding, name='consumer_shot_unbinding'),  | 
            |
| 62 | 63 | 
                ]  | 
            
| 63 | 64 | 
                 | 
            
| 64 | 65 | 
                urlpatterns += [  | 
            
                @@ -159,6 +160,7 @@ urlpatterns += [  | 
            ||
| 159 | 160 | 
                url(r'^admin/record/sale$', admin_views.record_sale, name='record_sale'),  | 
            
| 160 | 161 | 
                url(r'^admin/record/sale/batch$', admin_views.record_sale_batch, name='record_sale_batch'),  | 
            
| 161 | 162 | 
                url(r'^admin/record/warehouse$', admin_views.record_warehouse, name='record_warehouse'),  | 
            
| 163 | 
                + url(r'^admin/consumer/shot/unbinding/list$', consumer_admin_view.consumer_shot_unbinding_list, name='consumer_shot_unbinding_list'),  | 
            |
| 162 | 164 | 
                 | 
            
| 163 | 165 | 
                url(r'^admin/list/model$', admin_views.model_list, name='model_list'),  | 
            
| 164 | 166 | 
                url(r'^admin/list/distributor$', admin_views.distributor_list, name='distributor_list'),  | 
            
                @@ -0,0 +1,37 @@  | 
            ||
| 1 | 
                +# -*- coding: utf-8 -*-  | 
            |
| 2 | 
                +  | 
            |
| 3 | 
                +# Generated by Django 3.2.6 on 2023-03-01 07:25  | 
            |
| 4 | 
                +  | 
            |
| 5 | 
                +from django.db import migrations, models  | 
            |
| 6 | 
                +  | 
            |
| 7 | 
                +  | 
            |
| 8 | 
                +class Migration(migrations.Migration):  | 
            |
| 9 | 
                +  | 
            |
| 10 | 
                + dependencies = [  | 
            |
| 11 | 
                +        ('mch', '0066_auto_20230208_1344'),
               | 
            |
| 12 | 
                + ]  | 
            |
| 13 | 
                +  | 
            |
| 14 | 
                + operations = [  | 
            |
| 15 | 
                + migrations.CreateModel(  | 
            |
| 16 | 
                + name='ConsumeShotUnbindingInfo',  | 
            |
| 17 | 
                + fields=[  | 
            |
| 18 | 
                +                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
               | 
            |
| 19 | 
                +                ('status', models.BooleanField(default=True, help_text='Status', verbose_name='status')),
               | 
            |
| 20 | 
                +                ('created_at', models.DateTimeField(auto_now_add=True, help_text='Create Time', verbose_name='created_at')),
               | 
            |
| 21 | 
                +                ('updated_at', models.DateTimeField(auto_now=True, help_text='Update Time', verbose_name='updated_at')),
               | 
            |
| 22 | 
                +                ('brand_id', models.CharField(blank=True, db_index=True, help_text='品牌唯一标识', max_length=32, null=True, verbose_name='brand_id')),
               | 
            |
| 23 | 
                +                ('brand_name', models.CharField(blank=True, help_text='品牌名称', max_length=255, null=True, verbose_name='brand_name')),
               | 
            |
| 24 | 
                +                ('user_id', models.CharField(blank=True, db_index=True, help_text='用户唯一标识', max_length=32, null=True, verbose_name='user_id')),
               | 
            |
| 25 | 
                +                ('submit_pk', models.IntegerField(blank=True, default=0, help_text='消费者提交ID', null=True, verbose_name='submit_pk')),
               | 
            |
| 26 | 
                +                ('submit_at', models.DateTimeField(blank=True, help_text='消费者提交时间', null=True, verbose_name='submit_at')),
               | 
            |
| 27 | 
                +                ('model_id', models.CharField(blank=True, db_index=True, help_text='型号唯一标识', max_length=32, null=True, verbose_name='model_id')),
               | 
            |
| 28 | 
                +                ('sn', models.CharField(blank=True, db_index=True, help_text='序列号', max_length=16, null=True, verbose_name='sn')),
               | 
            |
| 29 | 
                +                ('reason', models.CharField(blank=True, db_index=True, help_text='解绑理由', max_length=256, null=True, verbose_name='model_id')),
               | 
            |
| 30 | 
                + ],  | 
            |
| 31 | 
                +            options={
               | 
            |
| 32 | 
                + 'verbose_name': '消费者镜头解绑记录',  | 
            |
| 33 | 
                + 'verbose_name_plural': '消费者镜头解绑记录',  | 
            |
| 34 | 
                +                'unique_together': {('user_id', 'submit_pk')},
               | 
            |
| 35 | 
                + },  | 
            |
| 36 | 
                + ),  | 
            |
| 37 | 
                + ]  | 
            
                @@ -0,0 +1,20 @@  | 
            ||
| 1 | 
                +# -*- coding: utf-8 -*-  | 
            |
| 2 | 
                +  | 
            |
| 3 | 
                +# Generated by Django 3.2.6 on 2023-03-01 10:21  | 
            |
| 4 | 
                +  | 
            |
| 5 | 
                +from django.db import migrations, models  | 
            |
| 6 | 
                +  | 
            |
| 7 | 
                +  | 
            |
| 8 | 
                +class Migration(migrations.Migration):  | 
            |
| 9 | 
                +  | 
            |
| 10 | 
                + dependencies = [  | 
            |
| 11 | 
                +        ('mch', '0067_consumeshotunbindinginfo'),
               | 
            |
| 12 | 
                + ]  | 
            |
| 13 | 
                +  | 
            |
| 14 | 
                + operations = [  | 
            |
| 15 | 
                + migrations.AlterField(  | 
            |
| 16 | 
                + model_name='consumeshotunbindinginfo',  | 
            |
| 17 | 
                + name='reason',  | 
            |
| 18 | 
                + field=models.CharField(blank=True, db_index=True, help_text='解绑理由', max_length=256, null=True, verbose_name='reason'),  | 
            |
| 19 | 
                + ),  | 
            |
| 20 | 
                + ]  | 
            
                @@ -9,6 +9,7 @@ from jsonfield import JSONField  | 
            ||
| 9 | 9 | 
                from shortuuidfield import ShortUUIDField  | 
            
| 10 | 10 | 
                from TimeConvert import TimeConvert as tc  | 
            
| 11 | 11 | 
                 | 
            
| 12 | 
                +from kodo.basemodels import BrandInfoMixin  | 
            |
| 12 | 13 | 
                from coupon.models import CouponInfo  | 
            
| 13 | 14 | 
                 | 
            
| 14 | 15 | 
                 | 
            
                @@ -770,6 +771,7 @@ class ConsumeInfoSubmitLogInfo(BaseModelMixin):  | 
            ||
| 770 | 771 | 
                'final_coupon_info': act.coupon_info(created_at=self.created_at) if act else self.coupon_info,  | 
            
| 771 | 772 | 
                'has_used': self.has_used,  | 
            
| 772 | 773 | 
                'used_at': self.used_at,  | 
            
| 774 | 
                + 'created_at': tc.local_string(utc_dt=self.created_at, format='%Y-%m-%d %H:%M'),  | 
            |
| 773 | 775 | 
                }  | 
            
| 774 | 776 | 
                 | 
            
| 775 | 777 | 
                @property  | 
            
                @@ -800,6 +802,44 @@ class ConsumeInfoSubmitLogInfo(BaseModelMixin):  | 
            ||
| 800 | 802 | 
                }  | 
            
| 801 | 803 | 
                 | 
            
| 802 | 804 | 
                 | 
            
| 805 | 
                +class ConsumeShotUnbindingInfo(BaseModelMixin, BrandInfoMixin):  | 
            |
| 806 | 
                + user_id = models.CharField(_(u'user_id'), max_length=32, blank=True, null=True, help_text=u'用户唯一标识', db_index=True)  | 
            |
| 807 | 
                + submit_pk = models.IntegerField(_(u'submit_pk'), default=0, blank=True, null=True, help_text=u'消费者提交ID')  | 
            |
| 808 | 
                + submit_at = models.DateTimeField(_(u'submit_at'), blank=True, null=True, help_text=u'消费者提交时间')  | 
            |
| 809 | 
                + model_id = models.CharField(_(u'model_id'), max_length=32, blank=True, null=True, help_text=u'型号唯一标识', db_index=True)  | 
            |
| 810 | 
                + sn = models.CharField(_(u'sn'), max_length=16, blank=True, null=True, help_text=u'序列号', db_index=True)  | 
            |
| 811 | 
                + reason = models.CharField(_(u'reason'), max_length=256, blank=True, null=True, help_text=u'解绑理由', db_index=True)  | 
            |
| 812 | 
                +  | 
            |
| 813 | 
                + class Meta:  | 
            |
| 814 | 
                + verbose_name = _(u'消费者镜头解绑记录')  | 
            |
| 815 | 
                + verbose_name_plural = _(u'消费者镜头解绑记录')  | 
            |
| 816 | 
                +  | 
            |
| 817 | 
                + unique_together = (  | 
            |
| 818 | 
                +            ('user_id', 'submit_pk'),
               | 
            |
| 819 | 
                + )  | 
            |
| 820 | 
                +  | 
            |
| 821 | 
                + def __unicode__(self):  | 
            |
| 822 | 
                + return '%d' % self.pk  | 
            |
| 823 | 
                +  | 
            |
| 824 | 
                + @property  | 
            |
| 825 | 
                + def admindata(self):  | 
            |
| 826 | 
                + from account.models import UserInfo  | 
            |
| 827 | 
                +  | 
            |
| 828 | 
                + info = ModelInfo.objects.get(model_id=self.model_id).fulldata  | 
            |
| 829 | 
                + user = UserInfo.objects.get(user_id=self.user_id)  | 
            |
| 830 | 
                +  | 
            |
| 831 | 
                +        return {
               | 
            |
| 832 | 
                + 'user_id': self.user_id,  | 
            |
| 833 | 
                + 'phone': user.phone,  | 
            |
| 834 | 
                + 'model_info': model_info,  | 
            |
| 835 | 
                + 'sn': self.sn,  | 
            |
| 836 | 
                + 'reason': self.reason,  | 
            |
| 837 | 
                + 'submit_pk': self.submit_pk,  | 
            |
| 838 | 
                + 'submit_at': self.submit_at,  | 
            |
| 839 | 
                + 'created_at': self.created_at,  | 
            |
| 840 | 
                + }  | 
            |
| 841 | 
                +  | 
            |
| 842 | 
                +  | 
            |
| 803 | 843 | 
                class ActivityInfo(BaseModelMixin):  | 
            
| 804 | 844 | 
                FIXED_EXPIRED_TIME = 0  | 
            
| 805 | 845 | 
                CHANGED_EXPIRED_TIME = 1  |